package frsf.cidisi.exercise.proyectoia.search.actions;

import java.util.ArrayList;

import frsf.cidisi.exercise.proyectoia.clasesProyectoIA.Esquina;
import frsf.cidisi.exercise.proyectoia.search.*;
import frsf.cidisi.faia.agent.search.SearchAction;
import frsf.cidisi.faia.agent.search.SearchBasedAgentState;
import frsf.cidisi.faia.state.AgentState;
import frsf.cidisi.faia.state.EnvironmentState;

public class SacarFoto extends SearchAction {

    /**
     * This method updates a tree node state when the search process is running.
     * It does not updates the real world state.
     */
    @Override
    public SearchBasedAgentState execute(SearchBasedAgentState s) {
        StateDrone agente = (StateDrone) s;
        
        int nivel = agente.getNivel();
        
        if(nivel==3){
        	Esquina esquina = agente.getEsquinaActual();
            int personas = esquina.getCantidadPersonas();
            
            boolean bandera = true;
            ArrayList<Integer> auxiliar = agente.getEsquinasFoto();
            for(int i=0; i<auxiliar.size();i++)
            {
            	 if(auxiliar.get(i) == (Integer)esquina.getCoordenada())
            		bandera=false;
            }
        	if(bandera && personas>0)
        	{
	        	//Resta las personas que acaba de controlar
	        	agente.setPersonasPendientesBajos(agente.getPersonasPendientesBajos()-esquina.getCantidadPersonas());
	        	agente.setPersonasPendientesMedios(agente.getPersonasPendientesMedios()-esquina.getCantidadPersonas());
	        	//Agrega esta esquina a esquinasVisitadas
	        	
	        	if(!auxiliar.contains(((Object)esquina)))
	        	{
		        	
					auxiliar.add((Integer)esquina.getCoordenada());
					agente.setEsquinasFoto(auxiliar);
	        	}
				//Quita (si es que esta) la esquina de la lista de Esquinas con personas 
				/*if(agente.getEsquinasconPersonas().contains((Object)esquina)){
					ArrayList<Esquina> array = agente.getEsquinasconPersonas();
					array.remove((Object)esquina);
					agente.setEsquinasconPersonas(array);
				}*/
				//Costo de la accion
				agente.incrementarCosto(getCost());
				agente.setIntensidades(0);
				return agente;
        	}
        }
        	
        return null;
    }

    /**
     * This method updates the agent state and the real world state.
     */
    @Override
    public EnvironmentState execute(AgentState ast, EnvironmentState est) {
        StateMapa ambiente = (StateMapa) est;
        StateDrone agente = ((StateDrone) ast);

        int nivel = ambiente.getNivDrone();
        Esquina esquinaDrone = agente.getEsquinaActual();
        Esquina esquinaAmbiente = ambiente.getCuadranteBajoDrone().getEsquinaIndex(esquinaDrone.getCoordenada());
        int personas = esquinaAmbiente.getCantidadPersonas();
        
        boolean bandera = true;
        ArrayList<Integer> auxiliar = agente.getEsquinasFoto();
        for(int i=0; i<auxiliar.size();i++)
        {
        	 if(auxiliar.get(i) == esquinaDrone.getCoordenada())
        		bandera=false;
        }
        
        if(nivel==3 && personas>0 && bandera){
        	//Se fija si encontro al victimario
        	if(esquinaAmbiente.getVictimarios()>0)
        		agente.setVictimarioHallado(true);
        	//Resta las personas que acaba de controlar
        	agente.setPersonasPendientesBajos(agente.getPersonasPendientesBajos()-esquinaAmbiente.getCantidadPersonas());
        	agente.setPersonasPendientesMedios(agente.getPersonasPendientesMedios()-esquinaAmbiente.getCantidadPersonas());
        	//Debe completar la cantidad de personas encontradas
        	agente.getMapa().getCuadranteIndex(agente.getCuadranteMedio().getNumero()).cuadranteBajoIndex(agente.getCuadranteBajo().getNumero()).getEsquinaIndex(esquinaDrone.getCoordenada()).setPersonas(esquinaAmbiente.getVictimas(), esquinaAmbiente.getVictimarios());
        	//Agrega esta esquina a esquinasFoto
			auxiliar.add((Integer)esquinaDrone.getCoordenada());
			agente.setEsquinasFoto(auxiliar);
			agente.incrementarCosto(getCost());
			agente.setIntensidades(1);
			return ambiente;
        }

        return null;
    }

    /**
     * This method returns the action cost.
     */
    @Override
    public Double getCost() {
        return new Double(0);
    }

    /**
     * This method is not important for a search based agent, but is essensial
     * when creating a calculus based one.
     */
    @Override
    public String toString() {
        return "SacarFoto";
    }
}